系列:「從單一 agent 到多 agent 集群,再到接進我的生活」;不設天數,第 11 篇
Day 10 收工時最誠實的一句話是:現在沒有綠燈紀錄。
而 Day 10 學到的第一件事是:綠燈不是證據。
那就把這兩句放在一起。這個專案信賴的燈不只一盞——本機全量、app 的 vitest、
GitHub 上的六七個 workflow、Day 10 自己加的兩道閘、幾條 ratchet。每一盞都在說
「綠」或「紅」,而我從來沒有把它們排成一列,逐盞問同一個問題:
你紅過嗎?
今天不修某個功能,做的是 Day 7 以來同一件事,只是對象換成燈本身:去量一件從來
沒有被量過的東西,然後修掉量出來的結果。

早上先讓 22 個 agent 對整個 repo 做一輪唯讀的對抗式調查(7 個調查員、每條主張一個
駁斥者、一個「你們漏了什麼」的批評者),不准跑 cargo。目的不是修,是拿到清單。
早上的清單有五盞;另外四盞是白天一路撞到的。全部排在一起:
| # | 燈 | 它說 | 實情 | 什麼時候撞到 |
|---|---|---|---|---|
| 1 | app vitest | 上次 655 passed | 08-28 之後沒整套量過 | 早上 |
| 2 | 本機 Rust 全量 | 「三千六百條全綠」 | 09-01 之後沒綠過;之後兩次都在 1849/3591 停;1742 條從沒跑過 | 早上 |
| 3 | paired_gate_check.sh |
Day 10 加的閘 | 對 259 個 commit 判 ✅,證據是一段 prose | 早上 |
| 4 | cargo-audit-nightly |
每晚守著 | 從 05-17 起 110/110 紅 | 早上 |
| 5 | Security Scan | 綠 | 08-24 起紅在一條真 advisory,沒人讀 | 早上 |
| 6 | gitleaks | PR 上的秘密掃描 | 最近 40/40 紅,從沒掃過一個 PR | 開 PR 時 |
| 7 | Dependency Review | PR 上的依賴審查 | 最近 40/40 紅,在這裡跑不起來 | 開 PR 時 |
| 8 | main 的 clippy | 綠 | main 從 08-12 就紅;stable 走到 1.98 又疊一層,沒人看見 | 開 PR 時 |
| 9 | Linux service install |
綠(Mac 上看不到) | 改名那天起壞,蓋在 clippy 下面 | 剝開 clippy 之後 |
還有一件不算燈、但決定所有燈有沒有人看的事:dev 分支上零次 workflow 觸發。
每一個 workflow 都只看 main,而 main 08-12 之後沒有任何 push 或 PR。這條分支上 57 個
commit,GitHub 一次都沒看過。
九盞。文章寫到這裡的時候,我還不知道幾盞是真的。下面按實際動手的順序。
這是清單裡唯一不搶 build lock 的燈,所以第一個跑:
Test Files 118 passed (118)
Tests 653 passed | 8 skipped (661)
Duration 19s
真綠。上一次有紀錄是 08-28 的 655 passed;中間 13 個 commit 動過 app/,沒有任何
workflow 跑它——不是它壞了,是沒有人看。一盞燈綠了一週沒人看,跟紅了一週沒人看,
對專案的意義是一樣的:零。
Day 10 寫:
apex4_phone_roundtrip.rs:77與test_rpc_forwarding.rs:103本來就會用簽章正確的
遠端請求打SELF_GATED_ROUTES裡的路由——那些測試會紅。
早上的調查員去讀了程式,駁斥者再去讀一次,結論一致:那兩條不紅。 它們用的auth_gate::signed_request 會替請求塞進 ConnectInfo,middleware 對 SELF_GATED_ROUTES
會站開,handler 只驗一次章。
真正紅的是另外兩條,而且是上一輪全量已經跑出來、我沒看的:
FAIL serve::api_events_route_tests::capability_query_route_is_wired_and_auth_gated
unauthenticated POST /rpc/capability-query must be rejected (401/403), got 500
FAIL serve::api_events_route_tests::onboarding_non_table_key_returns_graceful_500_not_panic
Missing request extension: ConnectInfo<SocketAddr> was not found
根因跟簽章無關:gate_api_and_rpc(serve.rs:267-272)的簽名要求一個ConnectInfo<SocketAddr> extractor,而 axum 0.7.9 的 from_fn 對沒有帶這個 extension
的請求,在進 middleware 本體之前就回 500。用 Request::builder() 直接打 router 的
測試沒有 peer address,就是這種請求。
第一條測試把那個 500 讀成「被拒絕」。它沒有。500 不是拒絕,也不是放行,它是壞掉。
而 assert_ne!(status, 401) 這種形狀的斷言,對 500 是綠的。
批評者的靜態掃描估同一家族約 27 條(lib 13 + test_security_t7 4 + t7b 9),
其中一條「拿到 500 也算綠」。這數字是估的,下面用跑的。
Day 7 的規矩:先量再修。所以第一件事不是改 middleware,是把全量在改動之前跑一遍,--no-fail-fast,讓 1742 條從沒跑過的測試一次全部報到:
START 18:17:42 HEAD=b7377c13 core_clean=0
Finished `test` profile in 18m 35s
Starting 3591 tests across 201 binaries (70 tests skipped)
Summary [ 176.001s ] 3591 tests run: 3546 passed, 45 failed, 70 skipped
EXIT=100
END 20:02:26
整輪 1 小時 45 分:編譯 18 分半、測試 3 分鐘、中間 81 分鐘在 macOS Gatekeeper——
nextest 對 201 個剛 link 出來的 binary 逐支 --list,每支停在 S 狀態等 syspolicyd
審核,約 25 秒一支,序列不平行。這件事本身也是一盞燈:Day 8 量過一次「45 分鐘」,
今天 201 支是 81 分鐘;它跟程式碼無關,跟 binary 數量成正比,而且 lib 一改就全部重付。
45 條紅。按 binary 分:
| binary | 紅 | 原因 |
|---|---|---|
lib serve::* |
15 | ConnectInfo 500 |
skill_rpc_skills |
14 | 3 條 ConnectInfo 500;11 條是另一件事(下面說) |
test_security_t7b |
8 | ConnectInfo 500 |
test_security_t7 |
4 | ConnectInfo 500 |
test_rpc_forwarding |
1 | 真 TCP 沒帶 connect info → 拿到 500 的純文字 body,「error decoding response body」 |
p9_the_shell_cannot_pin_itself |
1 | 跟 auth 無關:/sw.js 又把 HTML shell 放進 precache——Day 9 的 p9 測試,今天沒動 |
the_app_only_calls_routes_that_exist |
1 | 掃描器看不到 "{}/…" literal,checked=0,撞自己的下限 |
skill_rpc_skills 的 search_fts5_p99_latency |
1 | 時間斷言,兩次嘗試都超過 200 ms——跟 main 第四層同一條測試,這次量到的是 syspolicyd 佔著 40% CPU 的這台 Mac |
31 條同一個根因(ConnectInfo)。早上靜態估 27,實跑 31——差在哪?middleware 包的是
整個 router,extractor 在進函式之前就跑,所以連沒有閘的路徑也被 500 掉。靜態掃描只數了
「打閘的測試」,少算了「打任何路徑但沒帶地址的測試」。這也是今天的規矩:估的寫「估」,
跑完再寫數字。
然後是 skill_rpc_skills 那 11 條。它們有簽章——用的就是 auth_gate::signed_request,
帶 ConnectInfo、帶正確的 HMAC——卻被拒:
{"error":"unauthorized — bad or missing X-Cluster-Auth / X-Cluster-Timestamp / X-Cluster-Nonce"}
一個簽對的請求被說「簽章壞了」。這個形狀我在 Day 9 見過:middleware 驗一次、燒掉 nonce,
handler 自己再驗一次,第二次看到的就是重放。Day 9 為此建了 SELF_GATED_ROUTES——35 條
「handler 自己驗章、middleware 站開」的路由,而那份清單是從 serve.rs 反推出來的。/api/skills* 這組路由是 feature-gated、掛在另一個檔案,不在 serve.rs 裡,清單沒看到它。
「清點器只清點它名字裡那片」——如果證實,這是第六次。今晚沒證實:形狀一模一樣,但我沒有
去讀那個 handler,所以這裡寫「疑似」,明天先紅證再修。
我一開始把這 11 條也算進 ConnectInfo 家族,寫成「43 條同一根因」。看到 panic 訊息才
發現不是——同一個 binary 裡兩種紅,要一條一條讀訊息才分得開。按 binary 數是清點,
按訊息分才是量測。
第 44 條(route ratchet 的下限斷言)早上的批評者就預測到了:那條掃描器跳過所有"{}/..." 開頭的字面值,所以它看到 0 條 app 端路徑,先撞自己的 floor:
一條跟 hub_url 同行的字面路徑都沒有 —— 這條掃描已經對不上程式碼的形狀了
它紅得對——一個掃描器要先證明自己看得到東西,而它誠實地說了自己看不到——但它紅的
理由跟 ConnectInfo 無關,今天不修,留給 memory 契約裁定之後(修好它會立刻點名
memory.rs 那三條,沒有裁定就讓它紅,不 allowlist)。
改一行簽名、加一個 match:
peer: Option<axum::extract::ConnectInfo<std::net::SocketAddr>>,
// ...
let exempt = match peer {
Some(axum::extract::ConnectInfo(peer)) =>
crate::auth_gate::caller_is_exempt_local_ui(&state.cluster_manager, peer, req.headers()),
None => false, // 不知道你從哪來 → 不給本機豁免 → 必須簽章
};
fail-closed:沒有 peer address 的請求被當成遠端,得簽章。它不再 500,它 401/403。
兩條原本紅的測試不用改一個字——它們本來就在斷言正確的事,只是被 500 騙了。
同一個 commit 補一條放行側的測試,形狀是 Day 10 那道閘要求的:一條 Day 10 遷移過的
caller(get_provider_health → GET /api/providers/health),三個請求——
assert_eq!(200) 而且 body 的 providers 是陣列(門開了,第三個是紅證。少了它,前兩個一起綠也證明不了門在看簽章。
commit 414db8c4。不先跑全量——全量要重 link 201 支 binary、再付 80 分鐘 Gatekeeper;
先只建修之前紅的那 8 個 binary(加新測試那個),57 秒編完、4 分鐘 Gatekeeper:
Starting 2811 tests across 8 binaries (53 tests skipped)
Summary [ 82.956s ] 2811 tests run: 2795 passed, 16 failed, 53 skipped
同一批 binary,修之前 45 紅,修之後 16。兩條新的放行側測試都過:簽對 → 200 而且 body
是對的形狀;沒有地址 → 401/403,不是 500。
剩下的 16 條,每一條都讀了訊息:
| 紅 | 什麼 | 今晚怎麼處理 |
|---|---|---|
| 11 | skill_rpc_skills 的疑似雙重驗章(上面那段) |
修之前就是這個原因,這個 fix 本來就碰不到它;明天紅證再修 |
| 2 | lib squad_dispatch_tests 的 events_upload_rejects_too_many_parts_with_413、durable_status_survives_restart |
fail-closed 揭露的:它們模擬本機呼叫者,不簽章、期待 handler 的回答,卻從沒說過自己從哪來;以前 500、現在 401。修法是測試補一個 loopback 地址,兩行——但每改一次 lib-test 就重 link、重付 Gatekeeper,今晚不改 |
| 1 | p9_the_shell_cannot_pin_itself:/sw.js 的內容 |
跟 auth 無關,Day 9 的測試,今晚沒動 |
| 1 | route ratchet 的下限 | 另案(等 memory 裁定) |
| 1 | search_fts5_p99_latency |
機器,不是程式 |
所以「修之後」誠實的數字不是 0,是 16,而且五種。ConnectInfo 那 31 條是真的清掉了——
它們是這個 commit 唯一宣稱的事。
(待填:full22-after.log —— START/HEAD、Summary、EXIT、END;junit.xml 有沒有留下來)
Day 10 寫了 scripts/paired_gate_check.sh:改到閘的 PR,測試裡必須找得到放行側的斷言。
我還對它做了紅證,抓到它只看 + 行、看不到刪掉閘的 PR。我以為它是真的。
今天對整條分支跑它,從 origin/main 到 HEAD,259 個 commit:
paired-gate: ✅ 找到放行側斷言 ——
b/core/tests/one_signing_scheme.rs: `rpc_wire::sign_headers` (or `cli_config::signed_peer_request`, which \
它引用的「放行側斷言」,是一條 assert 訊息字串的續行。一段散文。
再看它接受的形狀:assert_ne!(status, 401)。而第二盞燈剛剛才教過——500 也滿足!= 401。這道閘的放行側,正好接受會被 500 騙的那種斷言。它從出生到現在,對真實的
diff 沒有說過一次「不」。
改嚴:先把字串字面值剝掉再比對;放行側要同時有「簽章請求的呼叫」跟「正向的狀態
斷言」(assert_eq!(…StatusCode::OK) 或 .is_success());assert_ne!(401) 不再算。
然後用五個合成 commit 做紅證:
| 情境 | 舊 script | 新 script |
|---|---|---|
碰閘 + 測試只有註解和字串裡的 send_signed( |
✅ 放行 | ❌ |
碰閘 + signed_request + assert_ne!(401) |
✅ 放行 | ❌ |
碰閘 + signed_request + assert_eq!(OK) |
✅ | ✅ |
把 require_cluster_auth 那行刪掉,沒測試 |
❌ | ❌ |
前端 authorize() + expect(200),沒簽章形狀 |
❌ | ❌ |
前兩列是重點:舊的放、新的擋。第三列證明新的不是把所有東西都擋掉。
順帶抓到一件更難堪的:WORKFLOW.md §1 的範例,教人寫的就是 assert_ne!(UNAUTHORIZED)。
文件教的斷言形狀,正是會被 500 騙的那種。 改了。
還有一件早上就知道、現在寫進文件的:這道閘沒有接進任何 workflow。WORKFLOW.md
第 64 行說「CI 用 scripts/paired_gate_check.sh 檢查這件事」,而 .github/workflows/
底下沒有一個檔案提到它。一個腳本在 repo 裡,跟一道閘在 CI 裡,是兩件事。文件改成
實話:腳本在,還沒接。
GitHub 上 cargo-audit-nightly 每晚跑,gh run list 看過去一排紅。早上的調查員往回翻:
gh issue create --label "security,cargo-audit"。一個告警系統,從出生那天起就沒有送出過任何一則告警。而它每晚都「跑了」。
而它每晚找到的 advisory 是什麼?它的 core 那步沒帶 --ignore RUSTSEC-2023-0071,
而 core/Cargo.lock:4156 就有 rsa 0.9.10——workflow 自己的註解說「rsa 只在
app/src-tauri」,是錯的。它每晚都被一條已知、有文件、不可修的 advisory 絆倒。
修法在 PR #370:core 也 ignore(理由跟 security.yml 同一段)、JSON 上傳成
artifact、告警步驟改成「有開著的 issue 就留言,沒有才開」、label 建起來、最後一步
明確 fail 並說為什麼。
接著開 PR 的時候,兩個 PR 幾秒內又紅了兩個 check。幾秒內紅的通常不是程式,是 check
本身。往回數最近 40 次 pull_request 的 Security Scan:
Resource not accessible by integration——contents: read。兩個都是 04-23 加的。從那之後每一個 PR 上都掛著兩個紅叉,而每一個 PR 都合併了。
紅叉掛久了,就變成背景。
修法一樣進 #370:gitleaks 補 pull-requests: read、關掉需要 write 的評論;
Dependency Review 在私有 repo 明講跳過,開了 GHAS 再拿掉那個條件。一個跑不了的
check 不是 check,留著它只是讓「紅」失去意義。
PR #369 只改兩個 Cargo.lock,結果 CI Fast 紅在 clippy:
error: using `chunks_exact` with a constant chunk size
--> src/embeddings/mod.rs:110:24
error: using `chunks_exact` with a constant chunk size
--> src/skill_wire.rs:2331:24
程式碼沒動。動的是 dtolnay/rust-toolchain@stable——它不釘版本,stable 走到 1.98,
帶來新的 lint chunks_exact_to_as_chunks。origin/main 08-12 之後沒有任何 push 或
PR,而 main 上的 workflow 只在 push/PR 時跑,所以它紅的那一天,沒有任何東西跑起來
讓人看見它紅了。
寫到這裡我以為故事是「main 本來綠的,工具鏈前進讓它紅了」。去翻 08-12 那次——
main 最後一次有人推它——的 CI Fast:那時就已經紅了,兩個 job 都紅,紅在下一節
那條測試。clippy 不是 main 變紅的原因,是疊上去的最新一層。main 從最後一次有人推它
那天起就是紅的,只是紅的理由換過。
兩處是同一個模式(decode little-endian f32 blob),改成 as_chunks::<4>()(1.88
起穩定),不用 #[allow] 蓋。PR #371,而且要先合它——不然 #369、#370 對 main 的
CI Fast 永遠紅。
這盞燈的教訓跟前面不一樣:它不是壞的。它是對的、而且沒有人看。一盞正確的燈在
沒有人看的地方變紅,跟一盞壞掉的燈,結果一樣。

PR #371 把 clippy 修掉,同一個 job 接著跑 cargo test --lib,在 ubuntu runner 上:
test service::linux::tests::systemd_unit_file_content_correct ... FAILED
ExecStart not substituted with bin path:
[Unit]
Description=Phantom Mesh agent daemon (per-user)
...
test result: FAILED. 2632 passed; 1 failed; 52 ignored
08-06 的改名把程式碼裡的替換目標改成 __SPECTYN_BIN__,而 templates/ 底下四個模板
還是 __PHANTOM_BIN__。所以 main 上的 spectyn service install,從改名那天起寫出來
的 unit file 就沒有 ExecStart——Linux 的安裝路徑壞了一個月。
這件事 dev 分支在 08-28 就修了(「四個模板滯留 phantom 佔位,install 全斷」),
從沒回流 main。而唯一會叫的那條測試,住在 #[cfg(target_os = "linux")] 的模組裡——
Mac 上跑多少次全量都碰不到它;它唯一活著的地方是 main 的 CI Fast,而那個 job 紅在
clippy 的那層上面,沒有人往下翻。
一盞燈蓋住另一盞燈。 第一盞紅得無關緊要(lint),第二盞紅得要命(安裝壞了),
從外面看是同一個紅叉。修法搬進 #371:四個模板、環境變數清單補 SPECTYN_PORT,
還有那條「模板不准再帶 phantom 時代名字」的 ratchet——讓 main 上也有一盞會為這件事
變紅的燈。
搬完,「Check + Clippy + Unit Tests」在 ubuntu 上綠了——這個 job 從 08-06 改名以來
第一次。然後同一個 run 的 Cargo Tests 露出第三層:
selfupdate_verify_tests::good_sha_passes
left: d01203a2… ← sha256("spectyn")
right: 3bb68de6… ← sha256("phantom")
改名把測試的 payload 從 "phantom" 改成 "spectyn",旁邊那個「已知正確的摘要」
沒跟著改。同一次改名、同一種債,第二筆。這條測試在 main 上從改名那天起一次都沒被
執行過:cargo test 跑到 lib 的 systemd 測試就停了,bin 的測試永遠排不到——
所以它甚至不是「紅了沒人看」,它是從來沒有機會紅。
三層,一個紅叉。剝的過程本身就是量測:每剝一層,才知道下面還有沒有。
修掉第三層,Cargo Tests 露出第四層:
search_fts5_p99_latency_under_200ms_with_1000_rows
FTS5 search p99 must stay <200ms over a ~1000-row bank, got p99=201ms
201 對 200。這一層跟前三層不同類:它不是程式錯,是一條時間斷言在 GitHub 的共用
runner 上量到了機器。dev 分支的 nextest.toml 早就把這類測試隔離成序列組、給一次
重試,理由寫在檔案頂端——「量到的是十五個行程搶同一顆核心,不是程式碼」。main 上沒有
這份設定,所以它是 main 上第一盞紅得對、但不是 bug 的燈。
我在這裡停。三層是改名債和工具鏈漂移,今天修得完;第四層要把那份隔離設定搬去
main,是另一張卡。Integration Tests 也紅著,今天沒看——寫在這裡,不寫成看過了。
三盞「紅得對」的燈裡最單純的一盞——也是一樣沒人讀。08-24 起 Security Scan 紅在 h2 0.4.14,
RUSTSEC-2026-0258(unbounded empty DATA frames,DoS,low)。08-17 那次綠,是因為
advisory 是 08-17 那天才進資料庫。
修法是兩個 lockfile 各一行:cargo update -p h2 → 0.4.19。PR #369。
順帶量到一件小事:cargo update -p h2 在 core 的 lock 裡不只動 h2,還重排了
windows-sys / socket2 的統一、刪了 10 條不可達的 windows-* 0.53.x。我先懷疑是 lock
跟 Cargo.toml 漂移,用 cargo metadata --locked 量——改前改後都 rc=0,沒漂移,是
cargo 重解的連鎖。懷疑要用量的殺,不是用猜的。
Day 10 有一節「我在昨天的文章裡寫錯一句」。今天升級成四句:
tauri.conf.json 的 externalBin 裡,copy-sidecar.sh 缺它會 fail,本機 Spectyn Mesh.app 裡有一支 18 MB 的它,daemon.rs::start_daemon 可以從對話畫面把它拉起來。the_other_daemon_does_not_ship.rs 只看三個 shell script 就宣稱「沒有東西出貨它」——"{}/..."第四句最難堪,因為它不是判斷錯誤。是知道錯了還按下發表——文字勘誤放明天,圖先
將就。這一篇的圖,沒裁定的事一律虛線。
一、「跑了」跟「亮了」是兩件事。 nightly 每晚都跑,從沒送出過告警。gitleaks 每個
PR 都跑,從沒掃過一個 PR。paired gate 對 259 個 commit 都跑了,從沒說過不。跑了只
證明程序存在。
二、正確的燈在沒人看的地方,等於壞的燈。 main 的 clippy 紅得對;vitest 綠得對。
兩盞都一週沒人看。專案得到的資訊是一樣的:零。燈的價值不在它對不對,在它紅的時候
有沒有人會看到——而 dev 分支上零次 workflow 觸發,意思是這條分支上的燈全部沒人看。

三、500 是第三種顏色。 拒絕是 401,放行是 200,而 500 兩邊都不是——它會讓assert_ne!(401) 綠、讓「該拒的被拒了」成立、讓一道閘以為自己在工作。今天三盞燈
(全量、paired gate、WORKFLOW.md 的範例)壞的方式都是同一個:把「不是 401」讀成
「放行了」。
syspolicyd。Terminal 進「開發者工具」豁免是操作者才能按的那一下。workflow_dispatch 跑一次 nightly,看 artifact 跟 issue 有沒有出現。ci-fast 加 dev/** trigger——但要在全量綠了之後,否則每次install.sh → service 重裝,順序不能反。/rpc/recall 誠實改名 / 蓋後端)、| 時間 | 事 | 證據 |
|---|---|---|
| 上午 | 22 agent 唯讀對抗式調查(7 調查員 / 14 駁斥者 / 1 批評者),不跑 cargo | 721 次工具呼叫,0 錯誤 |
| 18:17 | 全量「修之前」起跑,主 tree,--no-fail-fast |
HEAD b7377c13,core 乾淨 |
| 18:18 | app vitest 全套 | 118 檔 / 653 passed / 8 skipped / 0 failed / 19 s |
| 18:19 | 三個 commit 收掉 25 個未提交檔 | 8e867e3e e4eaee3e 08054359 |
| 18:20 | 量 origin/main 的 lockfile 有沒有漂移 | cargo metadata --locked rc=0,改前改後都是 |
| 18:24 | PR #369(h2 → 0.4.19)、PR #370(nightly) | label security cargo-audit 建了 |
| 18:25 | 兩個 PR 幾秒內紅三個 check | Dependency Review / gitleaks / SPEC-01 Serves: |
| 18:28 | PR #369 紅在 clippy → main 本身紅 | chunks_exact_to_as_chunks ×2,stable 1.98 |
| 18:31 | paired gate 改嚴 + 五個合成 commit 紅證 | c5948d9f |
| 18:32 | PR #371(clippy) | db0dced6 |
| 18:34 | PR #370 併入 gitleaks 權限 + Dependency Review 跳過 | 40/40 + 40/40,回溯到 06-10 |
| 18:36 | 全量編譯完成(18m35s),進 Gatekeeper | syspolicyd 40% CPU,~55 分鐘 |
| 19:20 | PR #371 clippy 過,cargo test --lib 露出第二層 |
2632 passed / 1 failed,__PHANTOM_BIN__ |
| 19:26 | 模板修正搬進 #371 | 83b41db6(從 dev 的 1e529998 搬四個模板 + ratchet) |
| 19:35 | #371 的 Unit Tests 綠(改名以來第一次);Cargo Tests 露出第三層 | GOOD_SHA = sha256("phantom") → c1ae414c |
| 19:37 | 翻 main 08-12 的最後一次 CI Fast:當時就紅 | run 31588217398,兩個 job 都紅在 systemd |
| 19:54 | 第四層:latency 斷言在共用 runner 上 201 ms vs 200 | 停在第三層,另開卡 |
| 20:02 | 全量「修之前」結束 | 3591 run / 3546 passed / 45 failed / 70 skipped;編譯 18m35s + Gatekeeper ~81 min + 實跑 176 s |
| 20:04 | ConnectInfo fail-closed + positive test + nextest slow-timeout/junit | 414db8c4 |
| 20:10 | targeted(8 binary):45 → 16 紅;兩條 positive test 過 | 2811 run / 2795 passed / 16 failed / 82.9 s |
| 20:13 | 全量「修之後」起跑 | HEAD 414db8c4,core 乾淨 |
| (待填) | 全量「修之後」結果 |